home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / Tickle-4.0 (tcl) / tcl / extend / src / tclXid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-03  |  11.1 KB  |  464 lines  |  [TEXT/MPS ]

  1. #ifdef MPW
  2. #    pragma segment TCLExtend
  3. #endif
  4.  
  5. /*
  6.  * tclXid.c --
  7.  *
  8.  * Tcl commands to access getuid, setuid, getgid, setgid and friends.
  9.  *---------------------------------------------------------------------------
  10.  * Copyright 1991-1993 Karl Lehenbauer and Mark Diekhans.
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose and without fee is hereby granted, provided
  14.  * that the above copyright notice appear in all copies.  Karl Lehenbauer and
  15.  * Mark Diekhans make no representations about the suitability of this
  16.  * software for any purpose.  It is provided "as is" without express or
  17.  * implied warranty.
  18.  *-----------------------------------------------------------------------------
  19.  * $Id: tclXid.c,v 2.7 1993/07/30 15:05:15 markd Exp $
  20.  *-----------------------------------------------------------------------------
  21.  */
  22.  
  23. #include "tclExtdInt.h"
  24.  
  25. /*
  26.  * Prototypes of internal functions.
  27.  */
  28. static int
  29. UseridToUsernameResult _ANSI_ARGS_((Tcl_Interp *interp,
  30.                                     int         userId));
  31.  
  32. static int
  33. UsernameToUseridResult _ANSI_ARGS_((Tcl_Interp *interp,
  34.                                     char       *userName));
  35.  
  36. static int
  37. GroupidToGroupnameResult _ANSI_ARGS_((Tcl_Interp *interp,
  38.                                       int         groupId));
  39.  
  40. static int
  41. GroupnameToGroupidResult _ANSI_ARGS_((Tcl_Interp *interp,
  42.                                       char       *groupName));
  43.  
  44.  
  45. #ifdef macintosh
  46.  
  47. extern char *tcl_getenv();
  48.  
  49. int
  50. getuid()
  51.     {
  52.     return 0;
  53.     }
  54.  
  55. int
  56. geteuid()
  57.     {
  58.     return 0;
  59.     }
  60.  
  61. int
  62. setuid(int id)
  63.     {
  64.     return 0;
  65.     }
  66.  
  67. int
  68. getgid()
  69.     {
  70.     return 0;
  71.     }
  72.  
  73. int
  74. getegid()
  75.     {
  76.     return 0;
  77.     }
  78.  
  79. int
  80. setgid(int gid)
  81.     {
  82.     return 0;
  83.     }
  84.  
  85. int
  86. getpid()
  87.     {
  88.     return 2; /* UNDONE */
  89.     }
  90.  
  91. int
  92. getppid()
  93.     {
  94.     return 1; /* UNDONE */
  95.     }
  96.  
  97. int
  98. getpgrp()
  99.     {
  100.     return 0;
  101.     }
  102.  
  103. #ifdef HAVE_SETPGID
  104.     setpgid (pid, pid)
  105.         int        pid;
  106.         int        gid;
  107.         {
  108.         }
  109. #else
  110.     setpgrp()
  111.         {
  112.         }
  113. #endif
  114.  
  115. #endif
  116.  
  117.  
  118. /*
  119.  *-----------------------------------------------------------------------------
  120.  *
  121.  * Tcl_IdCmd --
  122.  *     Implements the TCL id command:
  123.  *
  124.  *        id user ?name?
  125.  *        id convert user <name>
  126.  *
  127.  *        id userid ?uid?
  128.  *        id convert userid <uid>
  129.  *
  130.  *        id group ?name?
  131.  *        id convert group <name>
  132.  *
  133.  *        id groupid ?gid?
  134.  *        id convert groupid <gid>
  135.  *
  136.  *        id process
  137.  *        id process parent
  138.  *        id process group
  139.  *        id process group set
  140.  *
  141.  *        id effective user
  142.  *        id effective userid
  143.  *
  144.  *        id effective group
  145.  *        id effective groupid
  146.  *
  147.  * Results:
  148.  *  Standard TCL results, may return the UNIX system error message.
  149.  *
  150.  *-----------------------------------------------------------------------------
  151.  */
  152.  
  153. static int
  154. UseridToUsernameResult (interp, userId)
  155.     Tcl_Interp *interp;
  156.     int         userId;
  157.     {
  158. #ifdef macintosh
  159.     char *var = tcl_getenv("LOGIN");
  160.  
  161.     strcpy (interp->result, (var == NULL ? "anonymous" : var) );
  162. #else
  163.     uid_t          uid = (uid_t) userId;
  164.     struct passwd *pw = getpwuid (userId);
  165.  
  166.     if ((pw == NULL) || ((int) uid != userId))
  167.         {
  168.         sprintf (interp->result, "unknown user id: %d", userId);
  169.         endpwent ();
  170.         return TCL_ERROR;
  171.         }
  172.     strcpy (interp->result, pw->pw_name);
  173.     endpwent ();
  174. #endif
  175.     return TCL_OK;
  176.     }
  177.  
  178. static int
  179. UsernameToUseridResult (interp, userName)
  180.     Tcl_Interp *interp;
  181.     char       *userName;
  182.     {
  183. #ifdef macintosh
  184.     sprintf (interp->result, "%d", getuid());
  185. #else
  186.     struct passwd *pw = getpwnam (userName);
  187.  
  188.     if (pw == NULL) {
  189.         Tcl_AppendResult (interp, "unknown user id: ", userName, 
  190.                           (char *) NULL);
  191.         endpwent ();
  192.         return TCL_ERROR;
  193.     }
  194.     sprintf (interp->result, "%d", pw->pw_uid);
  195.     endpwent ();
  196. #endif
  197.     return TCL_OK;
  198.     }
  199.  
  200. static int
  201. GroupidToGroupnameResult (interp, groupId)
  202.     Tcl_Interp *interp;
  203.     int         groupId;
  204.     {
  205. #ifdef macintosh
  206.     char    *var = tcl_getenv("GROUP");
  207.     
  208.     strcpy( interp->result, (var == NULL ? "macintosh" : var) );
  209. #else
  210.     gid_t         gid = (gid_t) groupId;
  211.     struct group *grp = getgrgid (groupId);
  212.  
  213.     if ((grp == NULL) || ((int) gid != groupId))
  214.         {
  215.         sprintf (interp->result, "unknown group id: %d", groupId);
  216.         endgrent ();
  217.         return TCL_ERROR;
  218.         }
  219.     strcpy (interp->result, grp->gr_name);
  220.     endgrent ();
  221. #endif
  222.     return TCL_OK;
  223.     }
  224.  
  225. static int
  226. GroupnameToGroupidResult (interp, groupName)
  227.     Tcl_Interp *interp;
  228.     char       *groupName;
  229.     {
  230. #ifdef macintosh
  231.     sprintf(interp->result, "%d", getgid());
  232. #else
  233.     struct group *grp = getgrnam (groupName);
  234.     if (grp == NULL) {
  235.         Tcl_AppendResult (interp, "unknown group id: ", groupName,
  236.                           (char *) NULL);
  237.         return TCL_ERROR;
  238.     }
  239.     sprintf (interp->result, "%d", grp->gr_gid);
  240. #endif
  241.     return TCL_OK;
  242.     }
  243.  
  244. int
  245. Tcl_IdCmd (clientData, interp, argc, argv)
  246.     ClientData  clientData;
  247.     Tcl_Interp *interp;
  248.     int         argc;
  249.     char      **argv;
  250.     {
  251.     struct passwd *pw;
  252.     struct group *grp;
  253.     int           uid, gid;
  254.     pid_t         pid;
  255.  
  256.     if (argc < 2) 
  257.         goto bad_args;
  258.  
  259.     /*
  260.      * If the first argument is "convert", handle the conversion.
  261.      */
  262.     if (STREQU (argv[1], "convert")) {
  263.         if (argc != 4) {
  264.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  265.                               " convert arg arg", (char *) NULL);
  266.             return TCL_ERROR;
  267.         }
  268.  
  269.         if (STREQU (argv[2], "user"))
  270.             return UsernameToUseridResult (interp, argv[3]);
  271.  
  272.         if (STREQU (argv[2], "userid")) {
  273.             if (Tcl_GetInt (interp, argv[3], &uid) != TCL_OK) 
  274.                 return TCL_ERROR;
  275.             return UseridToUsernameResult (interp, uid);
  276.         }
  277.  
  278.         if (STREQU (argv[2], "group"))
  279.             return GroupnameToGroupidResult (interp, argv[3]);
  280.  
  281.         if (STREQU (argv[2], "groupid")) {
  282.             if (Tcl_GetInt (interp, argv[3], &gid) != TCL_OK)
  283.                 return TCL_ERROR;
  284.             return GroupidToGroupnameResult (interp, gid);
  285.  
  286.         }
  287.         goto bad_three_arg;
  288.     }
  289.  
  290.     /*
  291.      * If the first argument is "effective", return the effective user ID,
  292.      * name, group ID or name.
  293.      */
  294.     if (STREQU (argv[1], "effective")) {
  295.         if (argc != 3) {
  296.             Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  297.                               " effective arg", (char *) NULL);
  298.             return TCL_ERROR;
  299.         }
  300.  
  301.         if (STREQU (argv[2], "user"))
  302.             return UseridToUsernameResult (interp, geteuid ());
  303.  
  304.         if (STREQU (argv[2], "userid")) {
  305.             sprintf (interp->result, "%d", geteuid ());
  306.             return TCL_OK;
  307.         }
  308.  
  309.         if (STREQU (argv[2], "group"))
  310.             return GroupidToGroupnameResult (interp, getegid ());
  311.  
  312.         if (STREQU (argv[2], "groupid")) {
  313.             sprintf (interp->result, "%d", getegid ());
  314.             return TCL_OK;
  315.         }
  316.         goto bad_three_arg;
  317.     }
  318.  
  319.     /*
  320.      * If the first argument is "process", return the process ID, parent's
  321.      * process ID, process group or set the process group depending on args.
  322.      */
  323.     if (STREQU (argv[1], "process")) {
  324.         if (argc == 2) {
  325.             sprintf (interp->result, "%d", getpid ());
  326.             return TCL_OK;
  327.         }
  328.  
  329.         if (STREQU (argv[2], "parent")) {
  330.             if (argc != 3) {
  331.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  332.                                   " process parent", (char *) NULL);
  333.                 return TCL_ERROR;
  334.             }
  335.             sprintf (interp->result, "%d", getppid ());
  336.             return TCL_OK;
  337.         }
  338.         if (STREQU (argv[2], "group")) {
  339.             if (argc == 3) {
  340.                 sprintf (interp->result, "%d", getpgrp ());
  341.                 return TCL_OK;
  342.             }
  343.             if ((argc != 4) || !STREQU (argv[3], "set")) {
  344.                 Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  345.                                   " process group ?set?", (char *) NULL);
  346.                 return TCL_ERROR;
  347.             }
  348. #ifdef HAVE_SETPGID
  349.             pid = getpid ();
  350.             setpgid (pid, pid);
  351. #else
  352.             setpgrp ();
  353. #endif
  354.             return TCL_OK;
  355.         }
  356.         Tcl_AppendResult (interp, tclXWrongArgs, argv [0], 
  357.                           " process ?parent|group|group? ?set?",
  358.                           (char *) NULL);
  359.         return TCL_ERROR;
  360.     }
  361.  
  362.     /*
  363.      * Handle setting or returning the user ID or group ID (by name or number).
  364.      */
  365.     if (argc > 3)
  366.         goto bad_args;
  367.  
  368.     if (STREQU (argv[1], "user")) {
  369.         if (argc == 2) {
  370.             return UseridToUsernameResult (interp, getuid ());
  371.         } else {
  372. #ifdef macintosh
  373.             if ( strcmp( argv[2], tcl_getenv("LOGIN") ) != 0 )
  374.                 goto name_doesnt_exist;
  375. #else
  376.             pw = getpwnam (argv[2]);
  377.             if (pw == NULL)
  378.                 goto name_doesnt_exist;
  379.             if (setuid (pw->pw_uid) < 0)
  380.                 goto cannot_set_name;
  381.             endpwent ();
  382. #endif
  383.             return TCL_OK;
  384.         }
  385.     }
  386.  
  387.     if (STREQU (argv[1], "userid")) {
  388.         if (argc == 2) {
  389.             sprintf (interp->result, "%d", getuid ());
  390.             return TCL_OK;
  391.         } else {
  392.             if (Tcl_GetInt (interp, argv[2], &uid) != TCL_OK)
  393.                 return TCL_ERROR;
  394.             if (setuid ((uid_t) uid) < 0) 
  395.                 goto cannot_set_name;
  396.             return TCL_OK;
  397.         }
  398.     }
  399.  
  400.     if (STREQU (argv[1], "group")) {
  401.         if (argc == 2) {
  402.             return GroupidToGroupnameResult (interp, getgid ());
  403.         } else {
  404. #ifdef macintosh
  405.             if ( strcmp( argv[2], tcl_getenv("GROUP") ) != 0 )
  406.                 goto name_doesnt_exist;
  407. #else
  408.             grp = getgrnam (argv[2]);
  409.             if (grp == NULL)
  410.                 goto name_doesnt_exist;
  411.             if (setgid (grp->gr_gid) < 0)
  412.                 goto cannot_set_name;
  413.             endgrent ();
  414. #endif
  415.             return TCL_OK;
  416.         }
  417.     }
  418.  
  419.     if (STREQU (argv[1], "groupid")) {
  420.         if (argc == 2) {
  421.             sprintf (interp->result, "%d", getgid ());
  422.             return TCL_OK;
  423.         } else {
  424.             if (Tcl_GetInt (interp, argv[2], &gid) != TCL_OK)
  425.                 return TCL_ERROR;
  426.             if (setgid ((gid_t) gid) < 0)
  427.                 goto cannot_set_name;
  428.             return TCL_OK;
  429.         }
  430.     }
  431.     Tcl_AppendResult (interp, "bad arg: ", argv [0], 
  432.                       " second arg must be convert, effective, process, ",
  433.                       "user, userid, group or groupid", (char *) NULL);
  434.     return TCL_ERROR;
  435.  
  436.  
  437.   bad_three_arg:
  438.     Tcl_AppendResult (interp, "bad arg: ", argv [0], ": ", argv[1],
  439.                       ": third arg must be user, userid, group or groupid",
  440.                       (char *) NULL);
  441.     return TCL_ERROR;
  442.   bad_args:
  443.     Tcl_AppendResult (interp, tclXWrongArgs, argv [0], " arg ?arg..?",
  444.                       (char *) NULL);
  445.     return TCL_ERROR;
  446.  
  447.   name_doesnt_exist:
  448.     Tcl_AppendResult (interp, " \"", argv[2], "\" does not exists",
  449.                       (char *) NULL);
  450. #ifndef macintosh
  451.     endpwent ();
  452.     endgrent ();
  453. #endif
  454.     return TCL_ERROR;
  455.  
  456.   cannot_set_name:
  457.     interp->result = Tcl_PosixError (interp);
  458. #ifndef macintosh
  459.     endpwent ();
  460.     endgrent ();
  461. #endif
  462.     return TCL_ERROR;
  463. }
  464.